//
//  IMAudioRecorderManager.m
//  YuanXinChat
//
//  Created by 晏德智 on 2017/8/18.
//  Copyright © 2017年 晏德智. All rights reserved.
//

#import "AudioManager.h"
#import <AVFoundation/AVFoundation.h>

#define ERROR_AUDIO_DOMAIN @"LLAudioManager_Domain"

//amr临时目录
#define AMR_AUDIO_TMP_FOLDER @"amrAudioTmp"

//wav临时目录
#define WAV_AUDIO_TMP_FOLDER @"wavAudioTmp"

//录音需要的最短时间
#define MIN_RECORD_TIME_REQUIRED 1

//录音允许的最长时间
#define MAX_RECORD_TIME_ALLOWED 60

@interface AudioManager () <AVAudioRecorderDelegate, AVAudioPlayerDelegate>

@property (weak, nonatomic) id<AudioRecordDelegate> recordDelegate;
@property (weak, nonatomic) id<AudioPlayDelegate> playerDelegate;
@property (nonatomic) id userinfo;

@property (nonatomic) AVAudioSession *audioSession;

@property (nonatomic) AVAudioRecorder *recorder;
@property (nonatomic) AVAudioPlayer *audioPlayer;

@property (nonatomic) NSDictionary *recordSetting;

@property (nonatomic) dispatch_block_t block;

@property (nonatomic, copy) NSString *previousCategory;

@property (nonatomic) BOOL isCancelRecording;
@property (nonatomic) BOOL isFinishRecording;

@property (nonatomic, strong) NSString *basePath;
@property (nonatomic, strong) NSString *amrAudioTmpPath;
@property (nonatomic, strong) NSString *wavAudioTmpPath;

@end



@implementation AudioManager {
    CFTimeInterval startTime;
    NSTimeInterval maxRecordTime;
    NSTimer *timer;
    
    NSDate *startDate;
    //    NSDate *endDate;
    NSTimeInterval endDuration;
    BOOL isPlaySessionActive;
}

@synthesize audioTmpPath = _audioTmpPath;


+ (instancetype)shareInstance{
    static AudioManager *_audioManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _audioManager = [[self alloc] init];
    });
    
    return _audioManager;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        self.audioSession = [AVAudioSession sharedInstance];
        [self setupAudioTmpPath];
    }
    
    return self;
}

- (void)setupAudioTmpPath {
    NSString *strTemPath = self.audioTmpPath;
    if([[self class] createDirectory:strTemPath]){
        self.basePath = strTemPath;
        NSString *path = [strTemPath stringByAppendingPathComponent:AMR_AUDIO_TMP_FOLDER];
        if([[self class] createDirectory:path]){
            self.amrAudioTmpPath = path;
        }
        
        path = [strTemPath stringByAppendingPathComponent:WAV_AUDIO_TMP_FOLDER];
        if([[self class] createDirectory:path]){
            self.wavAudioTmpPath = path;
        }
    }
}

- (NSString *)audioTmpPath {
    if (!_audioTmpPath) {
        _audioTmpPath = [NSString stringWithFormat:@"%@/Library/appdata/audiobuffer", NSHomeDirectory()];
    }
    
    return _audioTmpPath;
}

- (void)setAudioTmpPath:(NSString *)audioTmpPath {
    if (![_audioTmpPath isEqualToString:audioTmpPath]) {
        _audioTmpPath = audioTmpPath;
        [self setupAudioTmpPath];
    }
}

- (NSDictionary *)recordSetting {
    if (!_recordSetting) {
        _recordSetting = [[NSDictionary alloc] initWithObjectsAndKeys:
                          //采样率,影响音频的质量）
                          [NSNumber numberWithFloat: 8000.0],AVSampleRateKey,
                          ////设置录音格式
                          [NSNumber numberWithInt: kAudioFormatLinearPCM],AVFormatIDKey,
                          //线性采样位数  8、16、24、32
                          [NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,
                          //录音通道数  1 或 2
                          [NSNumber numberWithInt: 1], AVNumberOfChannelsKey,
                          nil];
    }
    
    return _recordSetting;
}


#pragma mark - 录音

- (void)requestRecordPermission:(void (^)(NSString * permission))callback {
    switch (self.audioSession.recordPermission) {
        case AVAudioSessionRecordPermissionGranted:
            callback(@"Granted");
            break;
        case AVAudioSessionRecordPermissionDenied:
            callback(@"Denied");
            break;
        case AVAudioSessionRecordPermissionUndetermined:
            callback(@"Undetermined");
            break;
    }
}

- (void)checkAvailabilityWithDelegate:(id<AudioRecordDelegate>)delegate   callback:(void (^)(NSError *error))callback {
    if (!callback)
        return;
    [self.audioSession requestRecordPermission:^(BOOL granted) {
        //第一步：拥有访问麦克风的权限
        if (!granted) {
            NSError *error = [NSError errorWithDomain:ERROR_AUDIO_DOMAIN
                                                 code:kLLErrorRecordTypeAuthorizationDenied
                                             userInfo:nil];
            callback(error);
            return;
        }else {
            if ([delegate respondsToSelector:@selector(audioRecordAuthorizationDidGranted)]) {
                [delegate audioRecordAuthorizationDidGranted];
            }
        }
        
        //第二步：当前麦克风未使用
        if (self.isRecording) {
            NSError *error1 = [NSError errorWithDomain:ERROR_AUDIO_DOMAIN
                                                  code:kLLErrorRecordTypeMultiRequest
                                              userInfo:nil];
            
            callback(error1);
            return;
        }
        
        //第三步：设置AudioSession.category
        NSError *error;
        self.previousCategory = self.audioSession.category;
        BOOL success = [self.audioSession
                        setCategory:AVAudioSessionCategoryRecord
                        withOptions:AVAudioSessionCategoryOptionDuckOthers
                        error:&error];
        
        if (!success || error) {
            NSError *error1 = [NSError errorWithDomain:ERROR_AUDIO_DOMAIN
                                                  code:kLLErrorRecordTypeInitFailed
                                              userInfo:nil];
            
            callback(error1);
            return;
        }
        
        //第四步：激活AudioSession
        error = nil;
        success = [[AVAudioSession sharedInstance]
                   setActive:YES
                   withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation
                   error:&error];
        if (!success || error) {
            NSError *error1 = [NSError errorWithDomain:ERROR_AUDIO_DOMAIN
                                                  code:kLLErrorRecordTypeInitFailed
                                              userInfo:nil];
            
            callback(error1);
            return;
        }
        
        //第五步：创建临时录音文件
        NSURL *tmpAudioFile = [self.class wavPathWithName:[self.class randomFileName]];
        if (!tmpAudioFile) {
            NSError *error1 = [NSError errorWithDomain:ERROR_AUDIO_DOMAIN
                                                  code:kLLErrorRecordTypeCreateAudioFileFailed
                                              userInfo:nil];
            
            callback(error1);
            return;
        }
        
        //第六步：创建AVAudioRecorder
        error = nil;
        _recorder = [[AVAudioRecorder alloc] initWithURL:tmpAudioFile
                                                settings:self.recordSetting
                                                   error:&error];
        
        if(!_recorder || error) {
            _recorder = nil;
            NSError *error1 = [NSError errorWithDomain:ERROR_AUDIO_DOMAIN
                                                  code:kLLErrorRecordTypeInitFailed
                                              userInfo:nil];
            callback(error1);
            return ;
        }
        
        //第七步：开始录音
        success = [self.recorder record];
        startTime = CACurrentMediaTime();
        startDate = [NSDate date];
        if (!success) {
            _recorder = nil;
            NSError *error1 = [NSError errorWithDomain:ERROR_AUDIO_DOMAIN
                                                  code:kLLErrorRecordTypeRecordError
                                              userInfo:nil];
            callback(error1);
            return ;
            
        }
        
        callback(nil);
    }];
}


- (void)startRecordingWithDelegate:(id<AudioRecordDelegate>)delegate
{
    [self checkAvailabilityWithDelegate:delegate callback:^(NSError *error) {
        if (!error) {
            self.recordDelegate = delegate;
            self.isFinishRecording = NO;
            self.isCancelRecording = NO;
            self.isRecording = YES;
            self.recorder.delegate = self;
            
            [timer invalidate];
            
            if (self.recordDelegate && [self.recordDelegate respondsToSelector:@selector(audioRecordDurationDidChanged:)]){
                timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(timerHandler:) userInfo:nil repeats:YES];
                [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
            }
            
            //开启仪表计数功能,可以获取当前录音音量大小
            self.recorder.meteringEnabled = YES;
            maxRecordTime = MAX_RECORD_TIME_ALLOWED;
            if (self.recordDelegate && [self.recordDelegate respondsToSelector:@selector(audioRecordMaxRecordTime)]){
                maxRecordTime = [delegate audioRecordMaxRecordTime];
            }
            
            //录音音量变化
            [self updateVoiceMeter];
            
            if (self.recordDelegate && [self.recordDelegate respondsToSelector:@selector(audioRecordDidStartRecordingWithError:)]){
                
                _block = dispatch_block_create(0, ^{
                    [delegate audioRecordDidStartRecordingWithError:nil];
                });
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)((MIN_RECORD_TIME_REQUIRED + 0.25) * NSEC_PER_SEC)), dispatch_get_main_queue(), _block);
            }
            
            
            
        }else {
            if (delegate && [delegate respondsToSelector:@selector(audioRecordDidStartRecordingWithError:)]){
                
                [delegate audioRecordDidStartRecordingWithError:error];
            }
        }
        
    }];
    
}


//处理音量变化
- (void)updateVoiceMeter {
    
    __weak typeof(self) weakSelf =  self;
    
    __block BOOL isSendMsg = NO;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        while(weakSelf.isRecording) {
            [weakSelf.recorder updateMeters]; //更新测量值 前提必须要打开 meteringEnabled
            
            float   level;                // The linear 0.0 .. 1.0 value we need. // 最终获取的值 0~1之间
            float   minDecibels = -80.0f; // Or use -60dB, which I measured in a silent room. //最小分贝 -80 去除分贝过小的声音
            float   decibels = [weakSelf.recorder averagePowerForChannel:0]; //获取通道0的分贝
            if (decibels < minDecibels) //控制最小值 0
            {
                level = 0.0f;
            }
            else if (decibels >= 0.0f) //控制最大值 1
            {
                level = 1.0f;
            }
            else
            {
                float   root            = 2.0f;
                float   minAmp          = powf(10.0f, 0.05f * minDecibels); //最小分贝的波形幅度值 公式: db 分贝 A 波形幅度值   dB=20∗log(A)→A=pow(10,(db/20.0))
                float   inverseAmpRange = 1.0f / (1.0f - minAmp);
                float   amp             = powf(10.0f, 0.05f * decibels); //实时获取到波形幅度值 公式同上
                float   adjAmp          = (amp - minAmp) * inverseAmpRange; //(实时数据 - 最小数据)/(最大数据 - 最小数据)  应该计算的一个比例值吧
                
                level = powf(adjAmp, 1.0f / root); //开方? 这个不懂
            }
            
            //float theVal = level * 60; //扩大范围 0~1 -> 0~60
            
            //float averagePower = [weakSelf.recorder peakPowerForChannel:0];
            double lowPassResults = level;
            dispatch_async(dispatch_get_main_queue(), ^{
                [weakSelf.recordDelegate audioRecordDidUpdateVoiceMeter:lowPassResults];
            });
            
            if (weakSelf.recorder.currentTime >= maxRecordTime &&!isSendMsg) {
                isSendMsg = YES;
                if (weakSelf.recordDelegate && [weakSelf.recordDelegate respondsToSelector:@selector(audioRecordDurationTooLong)]){
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [weakSelf.recordDelegate audioRecordDurationTooLong];
                    });
                }
            }
            
            [NSThread sleepForTimeInterval:0.1];
        }
    });
}

- (void)timerHandler:(NSTimer *)timer {
    [self.recordDelegate audioRecordDurationDidChanged:self.recorder.currentTime];
}

/**
 *  停止录音
 */
- (void)stopRecording {
    if(!self.isRecording){
        return;
    }
    
    //录音时间过短，按照取消录音对待
    if(self.recorder.currentTime < MIN_RECORD_TIME_REQUIRED){
        self.isFinishRecording = NO;
        self.isCancelRecording = YES;
        
        [self willStopRecord];
        if (self.recordDelegate && [self.recordDelegate respondsToSelector:@selector(audioRecordDurationTooShort)]){
            [self.recordDelegate audioRecordDurationTooShort];
        }
        
    }else {
        self.isFinishRecording = YES;
        self.isCancelRecording = NO;
        
        [self willStopRecord];
    }
    
}


/**
 *  取消录音
 */
- (void)cancelRecording {
    if(!self.isRecording){
        return;
    }
    
    self.isFinishRecording = NO;
    self.isCancelRecording = YES;
    [self willStopRecord];
    if (self.recordDelegate && [self.recordDelegate respondsToSelector:@selector(audioRecordDidCancelled)]){
        [self.recordDelegate audioRecordDidCancelled];
    }
}


- (void)willStopRecord {
    endDuration = _recorder.currentTime;
    if (_recorder.isRecording)
        [self.recorder stop]; //stop后会调用代理finishing方法
    //endDate = [NSDate date];
    //self.isRecording = NO; // 放在这不准确
    
    if (!dispatch_block_testcancel(_block))
        dispatch_block_cancel(_block);
    _block = nil;
}

- (void)didStopRecord {
    _recorder.delegate = nil;
    _recorder = nil;
    self.recordDelegate = nil;
    self.isRecording = NO;
    self.isFinishRecording = NO;
    self.isCancelRecording = NO;
    maxRecordTime = 1<<10;
    startDate = nil;
    //    endDate = nil;
    endDuration = 0;
    
    if (self.previousCategory.length > 0) {
        [self.audioSession setCategory:self.previousCategory error:nil];
        self.previousCategory = nil;
    }
    
    [self.audioSession setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
}


#pragma mark - AVAudioRecorderDelegate
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder
                           successfully:(BOOL)flag {
    NSString *recordPath = [[_recorder url] path];
    
    if (!flag) {
        //录制出错
        if ([self.recordDelegate respondsToSelector:@selector(audioRecordDidFailed)]) {
            [self.recordDelegate audioRecordDidFailed];
        }
        
        NSFileManager *fm = [NSFileManager defaultManager];
        [fm removeItemAtPath:recordPath error:nil];
        
    }else if (self.isFinishRecording) {
        
        if ([self.recordDelegate respondsToSelector:@selector(audioRecordDidFinishSuccessed:duration:)]) {
            [self.recordDelegate audioRecordDidFinishSuccessed:recordPath duration:endDuration];
        }
        
        /*
        //录音格式转换，从wav转为amr
        NSString *amrFilePath = [[recordPath stringByDeletingPathExtension]
                                 stringByAppendingPathExtension:@"amr"];
        BOOL convertResult = [self convertWAV:recordPath toAMR:amrFilePath];
        if (convertResult) {
    
            if ([self.recordDelegate respondsToSelector:@selector(audioRecordDidFinishSuccessed:duration:)]) {
                [self.recordDelegate audioRecordDidFinishSuccessed:amrFilePath duration:endDuration];
            }
        
        }else {
            if ([self.recordDelegate respondsToSelector:@selector(audioRecordDidFailed)]) {
                [self.recordDelegate audioRecordDidFailed];
            }
        }
  */
        // 删除录的wav
        NSFileManager *fm = [NSFileManager defaultManager];
        [fm removeItemAtPath:recordPath error:nil];
       
    }else if (self.isCancelRecording) {
        // 删除录的wav
        NSFileManager *fm = [NSFileManager defaultManager];
        [fm removeItemAtPath:recordPath error:nil];
    }
    
    [self didStopRecord];
    
}

- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder
                                   error:(NSError *)error {
    NSLog(@"audioRecorderEncodeErrorDidOccur");
    if ([self.recordDelegate respondsToSelector:@selector(audioRecordDidFailed)]) {
        [self.recordDelegate audioRecordDidFailed];
    }
    
    [self didStopRecord];
}




#pragma mark - 播放录音

- (void)checkAvailabilityWithFile:(NSString *)wavFilePath callback:(void (^)(NSError *error))callback {
    [self stopCurrentPlaying];
    
    NSError *error;
    if (!isPlaySessionActive) {
        //设置AudioSession.category
        error = nil;
        self.previousCategory = self.audioSession.category;
        BOOL success = [self.audioSession
                        setCategory:AVAudioSessionCategoryPlayback
                        withOptions:AVAudioSessionCategoryOptionDuckOthers
                        error:&error];
        
        if (!success || error) {
            NSError *error1 = [NSError errorWithDomain:ERROR_AUDIO_DOMAIN
                                                  code:kLLErrorPlayTypeInitFailed
                                              userInfo:nil];
            
            callback(error1);
            return;
        }
        
        if([[self class] isHeadphone]){
            error = nil;
            //打开外放
            success = [self.audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker
                                       error:&error];
            if (!success || error) {
                NSError *error1 = [NSError errorWithDomain:ERROR_AUDIO_DOMAIN
                                                      code:kLLErrorPlayTypeInitFailed
                                                  userInfo:nil];
                
                callback(error1);
                return;
            }
            
        }
        
        //激活AudioSession
        error = nil;
        success = [[AVAudioSession sharedInstance]
                   setActive:YES
                   withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation
                   error:&error];
        if (!success || error) {
            NSError *error1 = [NSError errorWithDomain:ERROR_AUDIO_DOMAIN
                                                  code:kLLErrorPlayTypeInitFailed
                                              userInfo:nil];
            
            callback(error1);
            return;
        }
        
    }
    
    //保证WAV格式录音文件存在
    NSFileManager *fileManager = [NSFileManager defaultManager];
    // NSString *wavFilePath = wavFilePath;
    //[[amrFileName stringByDeletingPathExtension] stringByAppendingPathExtension:@"wav"];
    if (![fileManager fileExistsAtPath:wavFilePath]) {
            NSError *error1 = [NSError errorWithDomain:ERROR_AUDIO_DOMAIN
                                                  code:kLLErrorPlayTypeFileNotExist
                                              userInfo:nil];
            
            callback(error1);
            return ;
    }
    
    //创建AVAudioPlayer
    error = nil;
    NSURL *wavURL = [NSURL URLWithString:wavFilePath];
    _audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:wavURL error:&error];
    if(!_audioPlayer || error) {
        _audioPlayer = nil;
        NSError *error1 = [NSError errorWithDomain:ERROR_AUDIO_DOMAIN
                                              code:kLLErrorPlayTypeInitFailed
                                          userInfo:nil];
        callback(error1);
        return ;
    }
    
    //开始播放
    _audioPlayer.delegate = self;
    //修改音频会话类别
    
    //问题原因应该是在录音阶段，SDK设置音频会话类别为AVAudioSessionCategoryRecord，
    //这会停止其他应用的声音（比如iPod）并让你的应用也不能初始化音频回放（比如AVAudioPlayer）。
    //在这种模式下，你只能进行录音。使用这个类别，调用AVAudioPlayer的prepareToPlay会返回YES，但是调用play方法将返回NO。
    //主UI界面会照常工作。这时，即使你的设备屏幕被用户锁定了，应用的录音仍会继续。
    //而在播放完录制音频后需主动修改会话类别，所以播放音频前需要主动调用
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
    
    BOOL success = [_audioPlayer play];
    if (!success) {
        NSError *error1 = [NSError errorWithDomain:ERROR_AUDIO_DOMAIN
                                              code:kLLErrorPlayTypePlayError
                                          userInfo:nil];
        callback(error1);
        return ;
        
    }
    
    callback(nil);
}


// 播放音频，播放音频不需要特殊权限
- (void)startPlayingWithPath:(NSString *)aFilePath
                    delegate:(id<AudioPlayDelegate>)delegate
                    userinfo:(id)userinfo continuePlaying:(BOOL)continuePlaying {
    
    [self checkAvailabilityWithFile:aFilePath callback:^(NSError *error) {
        if (!error) {
            self.playerDelegate = delegate;
            self.userinfo = userinfo;
            self.isPlaying = YES;
            isPlaySessionActive = YES;
            
            if (delegate && [delegate respondsToSelector:@selector(audioPlayDidStarted:)]){
                [delegate audioPlayDidStarted:self.userinfo];
            }
            
            if (!continuePlaying && [[self class] currentVolumeLevel] <= kLLSoundVolumeLevelLow) {
                if (delegate && [delegate respondsToSelector:@selector(audioPlayVolumeTooLow)]){
                    [delegate audioPlayVolumeTooLow];
                }
            }
            
        }else {
            switch (error.code) {
                case kLLErrorPlayTypeInitFailed:
                case kLLErrorPlayTypeFileNotExist:
                case kLLErrorPlayTypePlayError:
                {
                    
                    //NSString *msg = @"遇到问题，暂时无法播放";
                    //todo:ydz
                    /*
                     */
                    break;
                }
                default:
                    break;
            }
            
            [self _stopPlaying];
        }
        
    }];
    
    
}

- (NSTimeInterval)getAudioDuration {
    return _audioPlayer.duration;
}

- (void)stopPlaying {
    if (!isPlaySessionActive) {
        return;
    }
    
    [self _stopPlaying];
    if (self.playerDelegate && [self.playerDelegate respondsToSelector:@selector(audioPlayDidStopped:)]){
        [self.playerDelegate audioPlayDidStopped:self.userinfo];
    }
    self.playerDelegate = nil;
    self.userinfo = nil;
    
}

- (void)_stopPlaying {
    [self _stopCurrentPlaying];
    
    if (self.previousCategory.length > 0) {
        [self.audioSession setCategory:self.previousCategory error:nil];
        self.previousCategory = nil;
    }
    
    [self.audioSession setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
    isPlaySessionActive = NO;
}

- (void)stopCurrentPlaying {
    if (!self.isPlaying)
        return;
    
    [self _stopCurrentPlaying];
    if (self.playerDelegate && [self.playerDelegate respondsToSelector:@selector(audioPlayDidStopped:)]){
        [self.playerDelegate audioPlayDidStopped:self.userinfo];
    }
}

- (void)_stopCurrentPlaying {
    if (_audioPlayer.isPlaying)
        [_audioPlayer stop]; //stop后不会调用delegate
    
    _audioPlayer = nil;
    self.isPlaying = NO;
}

- (void)pauseCurrentPlaying {
    if (!self.isPlaying)
        return;
    
    [self _pauseCurrentPlaying];
    if (self.playerDelegate && [self.playerDelegate respondsToSelector:@selector(audioPlayDidPaused:)]){
        [self.playerDelegate audioPlayDidPaused:self.userinfo];
    }
}

- (void)_pauseCurrentPlaying {
    if (_audioPlayer.isPlaying)
        [_audioPlayer pause]; //stop后不会调用delegate
    
    self.isPlaying = NO;
}

- (void)resumeCurrentPlaying {
    if (self.isPlaying)
        return;
    
    [self _resumeCurrentPlaying];
    if (self.playerDelegate && [self.playerDelegate respondsToSelector:@selector(audioPlayDidResumed:)]){
        [self.playerDelegate audioPlayDidResumed:self.userinfo];
    }
}

- (void)_resumeCurrentPlaying {
    [_audioPlayer play];
    
    self.isPlaying = YES;
}


#pragma mark - AVAudioPlayerDelegate

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player
                       successfully:(BOOL)flag{
    if (flag) {
        [self _stopCurrentPlaying];
        
        if ([self.playerDelegate respondsToSelector:@selector(audioPlayDidFinished:)]) {
            [self.playerDelegate audioPlayDidFinished:self.userinfo];
        }
    }else {
        [self _stopPlaying];
        
        if ([self.playerDelegate respondsToSelector:@selector(audioPlayDidFailed:)]) {
            [self.playerDelegate audioPlayDidFailed:self.userinfo];
        }
        self.playerDelegate = nil;
        self.userinfo = nil;
        
    }
    
}

- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player
                                 error:(NSError *)error{
    NSLog(@"audioPlayerDecodeErrorDidOccur");
    
    [self _stopPlaying];
    if (self.playerDelegate && [self.playerDelegate respondsToSelector:@selector(audioPlayDidFailed:)]){
        [self.playerDelegate audioPlayDidFailed:self.userinfo];
    }
    
    self.playerDelegate = nil;
    self.userinfo = nil;
}


#pragma mark - 录音文件存储

+ (NSString *)randomFileName {
    int x = arc4random() % 100000;
    NSTimeInterval time = [[NSDate date] timeIntervalSince1970];
    NSString *fileName = [NSString stringWithFormat:@"%d%d",(int)time,x];
    
    return fileName;
}


+ (NSURL *)amrPathWithName:(NSString *)fileName {
    
    if([AudioManager shareInstance].amrAudioTmpPath){
        
        NSURL *folderURL = [NSURL URLWithString:[AudioManager shareInstance].amrAudioTmpPath];
        
        NSString *filePathName = [NSString stringWithFormat:@"%@.amr", fileName];
        
        NSURL *filePath = [folderURL URLByAppendingPathComponent:filePathName];
        
        return filePath;
    }
    
    return nil;
}


+ (NSURL *)wavPathWithName:(NSString *)fileName {
    
    if([AudioManager shareInstance].wavAudioTmpPath){
        
        NSURL *folderURL = [NSURL URLWithString:[AudioManager shareInstance].wavAudioTmpPath];
        
        NSString *filePathName = [NSString stringWithFormat:@"%@.wav", fileName];
        
        NSURL *filePath = [folderURL URLByAppendingPathComponent:filePathName];
        
        return filePath;
    }
    
    return nil;
}

+ (BOOL)createDirectory:(NSString *)directory{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    BOOL r =YES;
    if(![fileManager fileExistsAtPath:directory]){
        NSError *error;
        [fileManager createDirectoryAtPath:directory
               withIntermediateDirectories:YES
                                attributes:nil
                                     error:&error];
        
        if (error) {
            r = NO;
            NSLog(@"创建文件失败 %@", error.localizedFailureReason);
        }
    }
    
    return r;
}


+ (NSURL *)createFolderWithName:(NSString *)folderName inDirectory:(NSString *)directory {
    NSString *path = [directory stringByAppendingPathComponent:folderName];
    NSURL *folderURL = nil;
    if([[self class] createDirectory:path]){
        folderURL = [NSURL URLWithString:path];
    }
    return folderURL;
}

#pragma mark - static Method
#pragma mark 获得当前的音量
+ (float)currentVolumn {
    //以下API已废弃
    //    UInt32 dataSize = sizeof(float);
    //
    //    AudioSessionGetProperty (kAudioSessionProperty_CurrentHardwareOutputVolume,
    //                             &dataSize,
    //                             &volume);
    float volume = [AVAudioSession sharedInstance].outputVolume;
    
    return volume;
}

+ (NSInteger)currentVolumeLevel {
    return round(16 *[self currentVolumn]);
}

+ (BOOL)isHeadphone {
    AVAudioSessionRouteDescription* route = [[AVAudioSession sharedInstance] currentRoute];
    for (AVAudioSessionPortDescription* desc in [route outputs]) {
        if ([[desc portType] isEqualToString:AVAudioSessionPortHeadphones])
            return YES;
    }
    return NO;
}

@end
